package com.xiaotao.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import com.xiaotao.entity.Room;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Admin
 */
@ServerEndpoint("/chatWebSocket/{roomId}/{userId}")
@Component
public class WebSocketService {

    static Logger log = LoggerFactory.getLogger(WebSocketService.class);

    private static int onlineCount = 0;

    // 用Room对象管理房间信息
    private static ConcurrentHashMap<String, Room> roomMap = new ConcurrentHashMap<>(); // key: roomId

    private Session session;
    private String userId = "";
    private String roomId = "";

    private static ApplicationContext applicationContext;

    public static void setApplicationContext(ApplicationContext context){
        applicationContext = context;
    }

    /**
     * 建立连接：新增用户列表广播
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("roomId") String roomId,@PathParam("userId") String userId){
        this.session = session;
        this.userId = userId;
        this.roomId = roomId;

        // 获取或创建房间（第一个进入的用户为房主，默认上限10人）
        Room room = roomMap.computeIfAbsent(roomId, k -> new Room(roomId, userId, 10));

        // 检查人数是否超过上限
        if (room.getUserMap().size() >= room.getMaxUsers()) {
            try {
                sendMessage("{\"type\":\"error\",\"message\":\"房间人数已满（上限" + room.getMaxUsers() + "人），请稍后再进！\"}");
                session.close();
                return;
            } catch (IOException e) {
                log.error("人数超限关闭连接失败", e);
                return;
            }
        }

        // 将用户加入房间
        room.getUserMap().put(userId, this);

        addOnlineCount();
        log.info("用户{}进入聊天室{}（房主：{}），当前人数：{}，上限：{}",
                userId, roomId, room.getOwnerId(), room.getUserMap().size(), room.getMaxUsers());

        try{
            // 系统消息增加房主标识
            JSONObject systemMsg = new JSONObject();
            systemMsg.put("type", "system");
            systemMsg.put("userId", "system");
            systemMsg.put("message", "进入聊天室成功");
            systemMsg.put("isOwner", userId.equals(room.getOwnerId()));
            systemMsg.put("roomId", this.roomId);
            systemMsg.put("roomOwner", room.getOwnerId());
            sendMessage(systemMsg.toJSONString());

            // 新增：用户加入后，广播更新用户列表（关键）
            broadcastUserList(room);
        }catch (IOException e){
            log.error("用户："+userId+",连接失败！！");
        }
    }

    /**
     * 关闭连接：新增用户列表广播
     */
    @OnClose
    public void onClose(){
        Room room = roomMap.get(roomId);
        if (room != null) {
            room.getUserMap().remove(userId);
            log.info("用户{}退出聊天室{}，当前人数：{}", userId, roomId, room.getUserMap().size());

            try {
                // 新增：用户离开后，广播更新用户列表（关键）
                broadcastUserList(room);
            } catch (IOException e) {
                log.error("广播用户列表失败", e);
            }
            // 房间为空则删除
            if (room.getUserMap().isEmpty()) {
                roomMap.remove(roomId);
                log.info("聊天室{}已解散（无用户）", roomId);
            }
        }

        subOnlineCount();
    }


    /**
     * 接收消息：完善踢人后的用户列表同步
     */
    @OnMessage
    public void onMessage(String message){
        Room room = roomMap.get(roomId);
        if (room == null) return;

        log.info("聊天室{}的用户{}发送消息：{}", roomId, userId, message);

        if(message!= null){
            log.info(message);
            try {
                JSONObject jsonObject = JSON.parseObject(message);
                String msgType = jsonObject.getString("type");

                // 处理踢人指令
                if ("kick".equals(msgType)) {
                    if (!userId.equals(room.getOwnerId())) {
                        sendMessage("{\"type\":\"error\",\"message\":\"无权限！只有房主可踢人\"}");
                        return;
                    }
                    String targetUserId = jsonObject.getString("targetUserId");
                    WebSocketService targetUser = room.getUserMap().get(targetUserId);
                    if (targetUser != null) {
                        targetUser.session.close();
                        room.getUserMap().remove(targetUserId);
                        broadcast(room, "{\"type\":\"system\",\"message\":\"用户" + targetUserId + "被房主踢出房间\"}");
                        // 新增：踢人后，广播更新用户列表（关键）
                        broadcastUserList(room);
                    }
                    return;
                }

                // 处理修改人数上限指令
                if ("setMaxUsers".equals(msgType)) {
                    if (!userId.equals(room.getOwnerId())) {
                        sendMessage("{\"type\":\"error\",\"message\":\"无权限！只有房主可修改人数上限\"}");
                        return;
                    }
                    int newMax = jsonObject.getIntValue("maxUsers");
                    room.setMaxUsers(newMax);
                    broadcast(room, "{\"type\":\"system\",\"message\":\"房间人数上限已修改为" + newMax + "人\"}");
                    return;
                }

                // 处理普通聊天消息
                jsonObject.put("userId", this.userId);
                jsonObject.put("roomId", this.roomId);
                jsonObject.put("type", "chat");

                room.getUserMap().forEach((u, service) -> {
                    if(u.equals(this.userId)) return;
                    try{
                        service.sendMessage(jsonObject.toJSONString());
                    }catch (IOException e){
                        e.printStackTrace();
                    }
                });

            } catch (Exception e) {
                log.error("消息处理失败", e);
            }
        }
    }

    /**
     * 广播消息到房间内所有用户
     */
    private void broadcast(Room room, String message) throws IOException {
        for (WebSocketService user : room.getUserMap().values()) {
            user.sendMessage(message);
        }
    }

    /**
     * 新增：广播用户列表（将Set转换为List，避免前端解析问题）
     */
    private void broadcastUserList(Room room) throws IOException {
        JSONObject userListMsg = new JSONObject();
        userListMsg.put("type", "system");
        // 关键：将用户ID集合转为List（因为Set在JSON序列化后可能被前端识别为对象而非数组）
        userListMsg.put("userList", new ArrayList<>(room.getUserMap().keySet()));
        broadcast(room, userListMsg.toJSONString());
    }

    /**
     * 服务器推送消息
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    // 以下方法不变
    public static  synchronized  int getOnlineCount(){
        return onlineCount;
    }

    public static  synchronized  void addOnlineCount(){
        WebSocketService.onlineCount++;
    }

    public static  synchronized void subOnlineCount(){
        WebSocketService.onlineCount--;
    }

}



//package com.xiaotao.service;
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.context.ApplicationContext;
//import org.springframework.stereotype.Component;
//
//import com.xiaotao.entity.Room;
//
//import javax.websocket.OnClose;
//import javax.websocket.OnMessage;
//import javax.websocket.OnOpen;
//import javax.websocket.Session;
//import javax.websocket.server.PathParam;
//import javax.websocket.server.ServerEndpoint;
//import java.io.IOException;
//import java.util.concurrent.ConcurrentHashMap;
//
///**
// * @author Admin
// */
//@ServerEndpoint("/chatWebSocket/{roomId}/{userId}")
//@Component
//public class WebSocketService {
//
//    static Logger log = LoggerFactory.getLogger(WebSocketService.class);
//
//    private static int onlineCount = 0;
//
//    // 修改：用Room对象管理房间信息，替代原有的roomUserMap
//    private static ConcurrentHashMap<String, Room> roomMap = new ConcurrentHashMap<>(); // key: roomId
//
//    private Session session;
//    private String userId = "";
//    private String roomId = "";
//
//    private static ApplicationContext applicationContext;
//
//    /**
//     * 解决引入外部类方法
//     * @param context
//     */
//    public static void setApplicationContext(ApplicationContext context){
//        applicationContext = context;
//    }
//
//    /**
//     * 建立连接：新增房主判定和人数限制
//     */
//    @OnOpen
//    public void onOpen(Session session,@PathParam("roomId") String roomId,@PathParam("userId") String userId){
//        this.session = session;
//        this.userId = userId;
//        this.roomId = roomId;
//
//        // 新增：获取或创建房间（第一个进入的用户为房主，默认上限10人）
//        Room room = roomMap.computeIfAbsent(roomId, k -> new Room(roomId, userId, 10));
//
//        // 新增：检查人数是否超过上限
//        if (room.getUserMap().size() >= room.getMaxUsers()) {
//            try {
//                // 发送人数超限提示并关闭连接
//                sendMessage("{\"type\":\"error\",\"message\":\"房间人数已满（上限" + room.getMaxUsers() + "人），请稍后再进！\"}");
//                session.close();
//                return;
//            } catch (IOException e) {
//                log.error("人数超限关闭连接失败", e);
//                return;
//            }
//        }
//
//        // 新增：将用户加入房间
//        room.getUserMap().put(userId, this);
//
//        addOnlineCount();
//        // 修改：日志补充房主和人数上限信息
//        log.info("用户{}进入聊天室{}（房主：{}），当前人数：{}，上限：{}",
//                userId, roomId, room.getOwnerId(), room.getUserMap().size(), room.getMaxUsers());
//
//        try{
//            // 修改：系统消息增加房主标识（isOwner）
//            JSONObject systemMsg = new JSONObject();
//            systemMsg.put("type", "system"); // 消息类型：系统通知
//            systemMsg.put("userId", "system");
//            systemMsg.put("message", "进入聊天室成功");
//            systemMsg.put("isOwner", userId.equals(room.getOwnerId())); // 标记当前用户是否为房主
//            systemMsg.put("roomId", this.roomId);
//            sendMessage(systemMsg.toJSONString());
//        }catch (IOException e){
//            log.error("用户："+userId+",连接失败！！");
//        }
//    }
//
//    /**
//     * 关闭连接：从房间移除用户
//     */
//    @OnClose
//    public void onClose(){
//        // 修改：从Room中移除用户
//        Room room = roomMap.get(roomId);
//        if (room != null) {
//            room.getUserMap().remove(userId);
//            log.info("用户{}退出聊天室{}，当前人数：{}", userId, roomId, room.getUserMap().size());
//
//            // 新增：如果房间为空，删除房间
//            if (room.getUserMap().isEmpty()) {
//                roomMap.remove(roomId);
//                log.info("聊天室{}已解散（无用户）", roomId);
//            }
//        }
//
//        subOnlineCount();
//    }
//
//
//    /**
//     * 接收消息：新增踢人、修改人数上限指令处理
//     */
//    @OnMessage
//    public void onMessage(String message){
//        Room room = roomMap.get(roomId);
//        if (room == null) return; // 房间不存在则忽略
//
//        log.info("聊天室{}的用户{}发送消息：{}", roomId, userId, message);
//
//        if(message!= null){
//            log.info(message);
//            try {
//                JSONObject jsonObject = JSON.parseObject(message);
//                String msgType = jsonObject.getString("type"); // 新增：消息类型
//
//                // 新增：处理踢人指令（仅房主可操作）
//                if ("kick".equals(msgType)) {
//                    // 验证是否为房主
//                    if (!userId.equals(room.getOwnerId())) {
//                        sendMessage("{\"type\":\"error\",\"message\":\"无权限！只有房主可踢人\"}");
//                        return;
//                    }
//                    String targetUserId = jsonObject.getString("targetUserId"); // 目标用户ID
//                    WebSocketService targetUser = room.getUserMap().get(targetUserId);
//                    if (targetUser != null) {
//                        // 关闭目标用户连接
//                        targetUser.session.close();
//                        room.getUserMap().remove(targetUserId);
//                        // 广播踢人通知
//                        broadcast(room, "{\"type\":\"system\",\"message\":\"用户" + targetUserId + "被房主踢出房间\"}");
//                    }
//                    return;
//                }
//
//                // 新增：处理修改人数上限指令（仅房主可操作）
//                if ("setMaxUsers".equals(msgType)) {
//                    if (!userId.equals(room.getOwnerId())) {
//                        sendMessage("{\"type\":\"error\",\"message\":\"无权限！只有房主可修改人数上限\"}");
//                        return;
//                    }
//                    int newMax = jsonObject.getIntValue("maxUsers");
//                    room.setMaxUsers(newMax);
//                    // 广播上限修改通知
//                    broadcast(room, "{\"type\":\"system\",\"message\":\"房间人数上限已修改为" + newMax + "人\"}");
//                    return;
//                }
//
//                // 原有逻辑：处理普通聊天消息
//                jsonObject.put("userId", this.userId);
//                jsonObject.put("roomId", this.roomId);
//                jsonObject.put("type", "chat"); // 标记为聊天消息
//
//                // 遍历房间内用户，转发消息（跳过自己）
//                room.getUserMap().forEach((u, service) -> {
//                    if(u.equals(this.userId)) return;
//                    try{
//                        service.sendMessage(jsonObject.toJSONString());
//                    }catch (IOException e){
//                        e.printStackTrace();
//                    }
//                });
//
//            } catch (Exception e) {
//                log.error("消息处理失败", e);
//            }
//        }
//    }
//
//    /**
//     * 新增：广播消息到房间内所有用户
//     */
//    private void broadcast(Room room, String message) throws IOException {
//        for (WebSocketService user : room.getUserMap().values()) {
//            user.sendMessage(message);
//        }
//    }
//
//    /**
//     * 服务器推送消息（原有逻辑不变）
//     */
//    public void sendMessage(String message) throws IOException {
//        this.session.getBasicRemote().sendText(message);
//    }
//
//
//    /**
//     * 获取在线人数（原有逻辑不变）
//     */
//    public static  synchronized  int getOnlineCount(){
//        return onlineCount;
//    }
//
//    /**
//     * 上线（原有逻辑不变）
//     */
//    public static  synchronized  void addOnlineCount(){
//        WebSocketService.onlineCount++;
//    }
//
//    /**
//     * 离线（原有逻辑不变）
//     */
//    public static  synchronized void subOnlineCount(){
//        WebSocketService.onlineCount--;
//    }
//    private void broadcastUserList(Room room) throws IOException {
//        JSONObject userListMsg = new JSONObject();
//        userListMsg.put("type", "system");
//        userListMsg.put("userList", room.getUserMap().keySet()); // 发送当前房间所有用户ID
//        broadcast(room, userListMsg.toJSONString());
//    }
//
//}










//package com.xiaotao.service;
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.context.ApplicationContext;
//import org.springframework.stereotype.Component;
//
//import javax.websocket.OnClose;
//import javax.websocket.OnMessage;
//import javax.websocket.OnOpen;
//import javax.websocket.Session;
//import javax.websocket.server.PathParam;
//import javax.websocket.server.ServerEndpoint;
//import java.io.IOException;
//import java.util.concurrent.ConcurrentHashMap;
//
///**
// * @author Admin
// */
//@ServerEndpoint("/chatWebSocket/{roomId}/{userId}")
//@Component
//public class WebSocketService {
//
//    static Logger log = LoggerFactory.getLogger(WebSocketService.class);
//
//    private static int onlineCount = 0;
//
//    private static ConcurrentHashMap<String, ConcurrentHashMap<String, WebSocketService>> roomUserMap = new ConcurrentHashMap<>();
//
//
////    private static ConcurrentHashMap<String,WebSocketService> webSocketServerMap = new ConcurrentHashMap<>();
//
//    private Session session;
//
//    private String userId = "";
//    private String roomId = "";
//
//    private static ApplicationContext applicationContext;
//
//    /**
//     * 解决引入外部类方法
//     * @param context
//     */
//    public static void setApplicationContext(ApplicationContext context){
//        applicationContext = context;
//    }
//
//    /**
//     * 建立连接
//     * @param session
//     * @param userId
//     */
//    @OnOpen
//    public void onOpen(Session session,@PathParam("roomId") String roomId,@PathParam("userId") String userId){
//        this.session = session;
//        this.userId = userId;
//        this.roomId = roomId;
//        roomUserMap.computeIfAbsent(roomId, k -> new ConcurrentHashMap<>());
//        roomUserMap.get(roomId).put(userId,this);
//
////        webSocketServerMap.put(userId,this);
//
//        addOnlineCount();
////        log.info("用户连接："+userId+"，当前在线人数为："+getOnlineCount());
//        log.info("用户{}进入聊天室{}，当前聊天室人数：{}", userId, roomId, roomUserMap.get(roomId).size());
//        try{
//            JSONObject systemMsg = new JSONObject();
//            systemMsg.put("userId", "system"); // 系统消息标记
//            systemMsg.put("message", "进入聊天室成功"); // 消息内容
//            systemMsg.put("roomId", this.roomId); // 房间号
//            sendMessage(systemMsg.toJSONString()); // 发送 JSON 格式字符串
//        }catch (IOException e){
//            log.error("用户："+userId+",连接失败！！");
//        }
//    }
//
//    /**
//     * 关闭连接
//     */
//    @OnClose
//    public void onClose(){
//        ConcurrentHashMap<String, WebSocketService> roomUsers = roomUserMap.get(roomId);
//        if (roomUsers !=null){
//            roomUsers.remove(userId);
//            if (roomUsers.isEmpty()){
//                roomUserMap.remove(roomId);
//            }
//        }
//        subOnlineCount();
//        log.info("用户{}退出聊天室{}，当前聊天室人数：{}", userId, roomId,
//                roomUsers != null ? roomUsers.size() : 0);
////        log.info("用户退出："+userId+",当前在线人数为："+getOnlineCount());
//    }
//
//
//    @OnMessage
//    public void onMessage(String message){
//        log.info("聊天室{}的用户{}发送消息：{}", roomId, userId, message);
//
//        if(message!= null){
//            log.info(message);
//            JSONObject jsonObject = JSON.parseObject(message);
//            jsonObject.put("userId",this.userId);
//            jsonObject.put("roomId",this.roomId);
//            ConcurrentHashMap<String, WebSocketService> roomUsers = roomUserMap.get(roomId);
//            if(roomUsers!=null){
//                roomUsers.forEach((u,service)->{
//                    if(u.equals(this.userId)) return;
//                    try{
//                        service.sendMessage(jsonObject.toJSONString());
//                    }catch (IOException e){
//                        e.printStackTrace();
//                    }
//                });
//            }
//
//
////            webSocketServerMap.forEach((u,m)->{
////                if(userId.contains(u)){
////                    return;
////                }
////                try {
////                    m.sendMessage(jsonObject.toJSONString());
////                } catch (IOException e) {
////                    e.printStackTrace();
////                }
////            });
//        }
//    }
//
//    /**
//     * 服务器推送消息
//     * @param message
//     * @throws IOException
//     */
//    public void sendMessage(String message) throws IOException {
//        this.session.getBasicRemote().sendText(message);
//    }
//
//
//    /**
//     * 获取在线人数
//     * @return
//     */
//    public static  synchronized  int getOnlineCount(){
//        return onlineCount;
//    }
//
//    /**
//     * 上线
//     */
//    public static  synchronized  void addOnlineCount(){
//        WebSocketService.onlineCount++;
//    }
//
//    /**
//     * 离线
//     */
//    public static  synchronized void subOnlineCount(){
//        WebSocketService.onlineCount--;
//    }
//
//}
